package com.opencee.cloud.msg.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.opencee.cloud.msg.api.constatns.MsgChannelType;
import com.opencee.cloud.msg.api.constatns.MsgConstants;
import com.opencee.cloud.msg.api.entity.MsgApplicationChannelEntity;
import com.opencee.cloud.msg.api.entity.MsgChannelConfigEntity;
import com.opencee.cloud.msg.api.vo.MsgChannelConfigVO;
import com.opencee.cloud.msg.mapper.MsgApplicationChannelMapper;
import com.opencee.cloud.msg.service.MsgApplicationChannelService;
import com.opencee.cloud.msg.service.MsgChannelConfigService;
import com.opencee.common.utils.RedisTemplateUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 应用消息通道授权 服务实现类
 *
 * @author liuyadu
 * @date
 */
@Service
public class MsgApplicationChannelServiceImpl extends SupperServiceImpl<MsgApplicationChannelMapper, MsgApplicationChannelEntity> implements MsgApplicationChannelService {
    @Autowired
    private MsgChannelConfigService msgChannelConfigService;
    @Autowired
    private RedisTemplateUtil redisTemplateUtil;

    /**
     * 设置通道
     *
     * @param appId
     * @param channelType
     * @param channelId
     */
    @Override
    public void setChannel(String appId, MsgChannelType channelType, Long channelId) {
        MsgChannelConfigVO config = msgChannelConfigService.getById(channelId);
        Assert.notNull(config, "通道信息不存在");
        Assert.isTrue(channelType.getValue().equals(config.getChannelType()), "设置的通道类型与通道不匹配");
        QueryWrapper<MsgApplicationChannelEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MsgApplicationChannelEntity::getAppId, appId)
                .eq(MsgApplicationChannelEntity::getChannelType, config.getChannelType());
        MsgApplicationChannelEntity entity = getOne(queryWrapper);
        if (entity == null) {
            entity = new MsgApplicationChannelEntity();
            entity.setAppId(appId);
            entity.setChannelType(config.getChannelType());
        }
        entity.setChannelId(channelId);
        boolean success = saveOrUpdate(entity);
        if (success) {
            String key = MsgConstants.CACHE_APP_CHANNEL_KEY + appId;
            redisTemplateUtil.del(key);
        }
    }

    /**
     * 移除通道
     *
     * @param appId
     * @param channelType
     */
    @Override
    public void removeChannel(String appId, MsgChannelType channelType) {
        QueryWrapper<MsgApplicationChannelEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MsgApplicationChannelEntity::getAppId, appId)
                .eq(MsgApplicationChannelEntity::getChannelType, channelType.getValue());
        boolean success = remove(queryWrapper);
        if (success) {
            String key = MsgConstants.CACHE_APP_CHANNEL_KEY + appId;
            redisTemplateUtil.del(key);
        }
    }

    /**
     * 获取应用通道
     *
     * @param appId
     * @return
     */
    @Override
    public List<MsgChannelConfigVO> getChannelList(String appId) {
        String key = MsgConstants.CACHE_APP_CHANNEL_KEY + appId;
        if (redisTemplateUtil.hasKey(key)) {
            return redisTemplateUtil.list(key);
        }
        QueryWrapper<MsgApplicationChannelEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MsgApplicationChannelEntity::getAppId, appId);
        List<MsgApplicationChannelEntity> list = this.list(queryWrapper);
        Set<Long> ids = list.stream().map(t -> t.getChannelId()).collect(Collectors.toSet());
        List<MsgChannelConfigEntity> configEntityList = msgChannelConfigService.listByIds(ids);
        List<MsgChannelConfigVO> configList = configEntityList.stream().map(t -> {
            MsgChannelConfigVO vo = new MsgChannelConfigVO();
            BeanUtils.copyProperties(t, vo);
            return vo;
        }).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(configList)) {
            redisTemplateUtil.setList(key, configList, 2, TimeUnit.HOURS);
        } else {
            redisTemplateUtil.set(key, configList, 1, TimeUnit.MINUTES);
        }
        return configList;
    }
}
